﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using CSharpTest.Net.Serialization;

namespace TEAA
{
    public class GenericPrimitiveListSerializer<TValue> : ISerializer<List<TValue>>
    {

        void ISerializer<List<TValue>>.WriteTo(List<TValue> value, Stream stream)
        {
            PrimitiveSerializer.Int32.WriteTo(value.Count, stream);

            TypeCode typeCode = Type.GetTypeCode(typeof(TValue));
            switch (typeCode)
            {
                case TypeCode.Boolean:
                    foreach(TValue tvalue in value)
                        PrimitiveSerializer.Boolean.WriteTo((bool)Convert.ChangeType(tvalue, typeof(bool)), stream);
                    break;

                case TypeCode.Int32:
                    foreach (TValue tvalue in value)
                        PrimitiveSerializer.Int32.WriteTo((int)Convert.ChangeType(tvalue, typeof(int)), stream);
                    break;

                case TypeCode.Double:
                    foreach (TValue tvalue in value)
                        PrimitiveSerializer.Double.WriteTo((double)Convert.ChangeType(tvalue, typeof(double)), stream);
                    break;

                case TypeCode.Char:
                    foreach (TValue tvalue in value)
                        PrimitiveSerializer.Char.WriteTo((char)Convert.ChangeType(tvalue, typeof(char)), stream);
                    break;

                case TypeCode.String:
                    foreach (TValue tvalue in value)
                        PrimitiveSerializer.String.WriteTo((string)Convert.ChangeType(tvalue, typeof(string)), stream);
                    break;

                case TypeCode.DateTime:
                    foreach (TValue tvalue in value)
                        PrimitiveSerializer.DateTime.WriteTo((DateTime)Convert.ChangeType(tvalue, typeof(DateTime)), stream);
                    break;
            }
        }

        List<TValue> ISerializer<List<TValue>>.ReadFrom(Stream stream)
        {
            int size = PrimitiveSerializer.Int32.ReadFrom(stream);
            List<TValue> values = new List<TValue>(size);

            TypeCode typeCode = Type.GetTypeCode(typeof(TValue));
            switch (typeCode)
            {
                case TypeCode.Boolean:
                    for (int i = 0; i < size; i++)
                        values.Add((TValue)Convert.ChangeType(PrimitiveSerializer.Boolean.ReadFrom(stream), typeof(TValue)));
                    return values;

                case TypeCode.Int32:
                    for (int i = 0; i < size; i++)
                        values.Add((TValue)Convert.ChangeType(PrimitiveSerializer.Int32.ReadFrom(stream), typeof(TValue)));
                    return values;

                case TypeCode.Double:
                    for (int i = 0; i < size; i++)
                        values.Add((TValue)Convert.ChangeType(PrimitiveSerializer.Double.ReadFrom(stream), typeof(TValue)));
                    return values;

                case TypeCode.Char:
                    for (int i = 0; i < size; i++)
                        values.Add((TValue)Convert.ChangeType(PrimitiveSerializer.Char.ReadFrom(stream), typeof(TValue)));
                    return values;

                case TypeCode.String:
                    for (int i = 0; i < size; i++)
                        values.Add((TValue)Convert.ChangeType(PrimitiveSerializer.String.ReadFrom(stream), typeof(TValue)));
                    return values;

                case TypeCode.DateTime:
                    for (int i = 0; i < size; i++)
                        values.Add((TValue)Convert.ChangeType(PrimitiveSerializer.DateTime.ReadFrom(stream), typeof(TValue)));
                    return values;
            }


            return default(List<TValue>);
        }

    }
}
